module.exports = function strrev (string) {
  //       discuss at: https://locutus.io/php/strrev/
  //      original by: Kevin van Zonneveld (https://kvz.io)
  //      bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  // reimplemented by: Brett Zamir (https://brett-zamir.me)
  //        example 1: strrev('Kevin van Zonneveld')
  //        returns 1: 'dlevennoZ nav niveK'
  //        example 2: strrev('a\u0301haB')
  //        returns 2: 'Baha\u0301' // combining
  //        example 3: strrev('A\uD87E\uDC04Z')
  //        returns 3: 'Z\uD87E\uDC04A' // surrogates
  //             test: 'skip-3'

  string = string + ''

  // Performance will be enhanced with the next two lines of code commented
  // out if you don't care about combining characters
  // Keep Unicode combining characters together with the character preceding
  // them and which they are modifying (as in PHP 6)
  // See https://unicode.org/reports/tr44/#Property_Table (Me+Mn)
  // We also add the low surrogate range at the beginning here so it will be
  // maintained with its preceding high surrogate

  const chars = [
    '\uDC00-\uDFFF',
    '\u0300-\u036F',
    '\u0483-\u0489',
    '\u0591-\u05BD',
    '\u05BF',
    '\u05C1',
    '\u05C2',
    '\u05C4',
    '\u05C5',
    '\u05C7',
    '\u0610-\u061A',
    '\u064B-\u065E',
    '\u0670',
    '\u06D6-\u06DC',
    '\u06DE-\u06E4',
    '\u06E7\u06E8',
    '\u06EA-\u06ED',
    '\u0711',
    '\u0730-\u074A',
    '\u07A6-\u07B0',
    '\u07EB-\u07F3',
    '\u0901-\u0903',
    '\u093C',
    '\u093E-\u094D',
    '\u0951-\u0954',
    '\u0962',
    '\u0963',
    '\u0981-\u0983',
    '\u09BC',
    '\u09BE-\u09C4',
    '\u09C7',
    '\u09C8',
    '\u09CB-\u09CD',
    '\u09D7',
    '\u09E2',
    '\u09E3',
    '\u0A01-\u0A03',
    '\u0A3C',
    '\u0A3E-\u0A42',
    '\u0A47',
    '\u0A48',
    '\u0A4B-\u0A4D',
    '\u0A51',
    '\u0A70',
    '\u0A71',
    '\u0A75',
    '\u0A81-\u0A83',
    '\u0ABC',
    '\u0ABE-\u0AC5',
    '\u0AC7-\u0AC9',
    '\u0ACB-\u0ACD',
    '\u0AE2',
    '\u0AE3',
    '\u0B01-\u0B03',
    '\u0B3C',
    '\u0B3E-\u0B44',
    '\u0B47',
    '\u0B48',
    '\u0B4B-\u0B4D',
    '\u0B56',
    '\u0B57',
    '\u0B62',
    '\u0B63',
    '\u0B82',
    '\u0BBE-\u0BC2',
    '\u0BC6-\u0BC8',
    '\u0BCA-\u0BCD',
    '\u0BD7',
    '\u0C01-\u0C03',
    '\u0C3E-\u0C44',
    '\u0C46-\u0C48',
    '\u0C4A-\u0C4D',
    '\u0C55',
    '\u0C56',
    '\u0C62',
    '\u0C63',
    '\u0C82',
    '\u0C83',
    '\u0CBC',
    '\u0CBE-\u0CC4',
    '\u0CC6-\u0CC8',
    '\u0CCA-\u0CCD',
    '\u0CD5',
    '\u0CD6',
    '\u0CE2',
    '\u0CE3',
    '\u0D02',
    '\u0D03',
    '\u0D3E-\u0D44',
    '\u0D46-\u0D48',
    '\u0D4A-\u0D4D',
    '\u0D57',
    '\u0D62',
    '\u0D63',
    '\u0D82',
    '\u0D83',
    '\u0DCA',
    '\u0DCF-\u0DD4',
    '\u0DD6',
    '\u0DD8-\u0DDF',
    '\u0DF2',
    '\u0DF3',
    '\u0E31',
    '\u0E34-\u0E3A',
    '\u0E47-\u0E4E',
    '\u0EB1',
    '\u0EB4-\u0EB9',
    '\u0EBB',
    '\u0EBC',
    '\u0EC8-\u0ECD',
    '\u0F18',
    '\u0F19',
    '\u0F35',
    '\u0F37',
    '\u0F39',
    '\u0F3E',
    '\u0F3F',
    '\u0F71-\u0F84',
    '\u0F86',
    '\u0F87',
    '\u0F90-\u0F97',
    '\u0F99-\u0FBC',
    '\u0FC6',
    '\u102B-\u103E',
    '\u1056-\u1059',
    '\u105E-\u1060',
    '\u1062-\u1064',
    '\u1067-\u106D',
    '\u1071-\u1074',
    '\u1082-\u108D',
    '\u108F',
    '\u135F',
    '\u1712-\u1714',
    '\u1732-\u1734',
    '\u1752',
    '\u1753',
    '\u1772',
    '\u1773',
    '\u17B6-\u17D3',
    '\u17DD',
    '\u180B-\u180D',
    '\u18A9',
    '\u1920-\u192B',
    '\u1930-\u193B',
    '\u19B0-\u19C0',
    '\u19C8',
    '\u19C9',
    '\u1A17-\u1A1B',
    '\u1B00-\u1B04',
    '\u1B34-\u1B44',
    '\u1B6B-\u1B73',
    '\u1B80-\u1B82',
    '\u1BA1-\u1BAA',
    '\u1C24-\u1C37',
    '\u1DC0-\u1DE6',
    '\u1DFE',
    '\u1DFF',
    '\u20D0-\u20F0',
    '\u2DE0-\u2DFF',
    '\u302A-\u302F',
    '\u3099',
    '\u309A',
    '\uA66F-\uA672',
    '\uA67C',
    '\uA67D',
    '\uA802',
    '\uA806',
    '\uA80B',
    '\uA823-\uA827',
    '\uA880',
    '\uA881',
    '\uA8B4-\uA8C4',
    '\uA926-\uA92D',
    '\uA947-\uA953',
    '\uAA29-\uAA36',
    '\uAA43',
    '\uAA4C',
    '\uAA4D',
    '\uFB1E',
    '\uFE00-\uFE0F',
    '\uFE20-\uFE26'
  ]

  const graphemeExtend = new RegExp('(.)([' + chars.join('') + ']+)', 'g')

  // Temporarily reverse
  string = string.replace(graphemeExtend, '$2$1')
  return string.split('').reverse().join('')
}
